import { cloneDeep } from 'lodash'
import type { Args, DataIn, Instance, Mutable } from './types'

export class Model {
  $data?: Record<string, any>

  static inst<T extends Model>(this: Instance<T>, data?: DataIn<T>, args: Args = []): T {
    const model = new this()
    if (data) {
      model.initialize(data as any, args)
      model.$data = data
    }
    return model
  }

  initialize(data: Mutable<this>, args: Args = []): void {
    Object.assign(this, data)
    args
  }

  datafy(): object {
    const data = JSON.parse(this.stringify())
    delete data.$data
    return data
  }

  stringify(): string {
    return JSON.stringify(this)
  }

  clone() {
    return cloneDeep(this)
  }

  reset() {
    this.initialize({ ...(this.constructor as any).inst(), ...this.$data })
  }
}
